Template Literal Types
文字列型にInterpolationができる
TypeScript v4.1~
PR
Intrinsic String Manipulation Types
関連
Template String Type Improvements
v4.3で入った改善
分けて理解する必要はないので、この名称はほぼ不要mrsekut.icon
#WIP
Template Literal Typesを取り除く
union
これもdistributeされるのねmrsekut.icon
code:ts
type VerticalAlignment = "top" | "middle" | "bottom";
type HorizontalAlignment = "left" | "center" | "right";
// Takes
// | "top-left" | "top-center" | "top-right"
// | "middle-left" | "middle-center" | "middle-right"
// | "bottom-left" | "bottom-center" | "bottom-right"
declare function setAlignment(value: ${VerticalAlignment}-${HorizontalAlignment}): void;
setAlignment("top-left"); // works!
setAlignment("top-middel"); // error!
setAlignment("top-pot"); // error! but good doughnuts if you're ever in Seattle
3*3で9個のパターンのみをみたす
例
https://github.com/type-challenges/type-challenges/issues/4264
Conditional Typesと組み合わせることで文字列パターンマッチができる
code:ts
A extends foo${infer B}baz ? B : never
型Aがfoohogebazなら、型Bはhoge
数値リテラルの文字列化
code:ts
N extends number ? `${N} : never
${}の中に、型を書ける
code:ts
type HelloStr = Hello, ${string};
書ける型は以下
'string | number | bigint | boolean | null | undefined'
as constを付けた時の挙動
code:ts
const world = 'world';
const str1 = Hello, ${world}!; // string
const str2 = Hello, ${world}! as const; // Hello, ${string}!
Interpolationしている文字列にas constを付けると、Template Literal Typesとして推論される
この辺に書いている例
keyof Tとかと組み合わせる時は、string &も付けてあげないといけない
template literal typesに入れられるのが、stringとかnumberとかだから
今まで「文字列でmethod名とか指定しないといけいないデザインになっているものってキモいなー」と思ってたけど、Template Literal Typesのある世界では全然そんなことないな
キモいなと思ってた理由が、「型安全ではない」点だったので、そこが解消されている
code:ts
type PropEventSource<T> = {
on<K extends string & keyof T>(
eventName: ${K}Changed,
callback: (newValue: TK) => void
): void;
};
/// Create a "watched object" with an 'on' method
/// so that you can watch for changes to properties.
declare function makeWatchedObject<T>(obj: T): T & PropEventSource<T>;
const person = makeWatchedObject({
firstName: 'Homer',
age: 42, // give-or-take
location: 'Springfield'
});
person.on('firstNameChanged', () => {
console.log(firstName was changed!);
});
// works! 'newName' is typed as 'string'
person.on('firstNameChanged', newName => {
// 'newName' has the type of 'firstName'
console.log(new name is ${newName.toUpperCase()});
});
// works! 'newAge' is typed as 'number'
person.on('ageChanged', newAge => {
if (newAge < 0) {
console.log('warning! negative age');
}
});
題材
Trim<S>
Replace<S, Froms, To>
CamelCase<S>
https://github.com/type-challenges/type-challenges/blob/master/questions/610-medium-camelcase/README.md
https://github.com/type-challenges/type-challenges/issues/4504
usecase
HTMLのquerySelector
https://github.com/microsoft/TypeScript/pull/40336#issuecomment-687739323
https://github.com/g-plane/type-gymnastics/tree/master/src/better-querySelector
routing
https://github.com/g-plane/type-gymnastics/tree/master/src/query-string-parser
https://twitter.com/Panda_Program/status/1339248778604232705
next
https://twitter.com/nkowne63/status/1300836662180638721
parse
https://twitter.com/nkowne63/status/1300836662180638721
https://zenn.dev/todesking/articles/d5c88b046c59f2ed76bb
https://dqn.fish/articles/2020-12-13-type-level-calculator
https://qiita.com/m_mitsuhide/items/337836c003e3e450884a
ts-sql
型レベルSQL DB
https://github.com/codemix/ts-sql
sqlpture
https://blog.andoshin11.me/posts/typescript-sql-interpretor
型レベルSQL Interpreter
麻雀
https://blog.manaten.net/entry/2021/12/03/030217
参考
https://medium.com/@Quramy/ネタ-typescript-型パズルで作るmini-interpreter-f21854cf3189
https://techracho.bpsinc.jp/yoshi/2020_09_04/97108
型レベルで、文字列を整数に変換する
https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#template-string-improvements
v4.3の変更
https://davidtimms.github.io/programming-languages/typescript/2020/11/20/exploring-template-literal-types-in-typescript-4.1.html